home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume17 / calentool / part16 < prev    next >
Encoding:
Internet Message Format  |  1991-04-06  |  55.2 KB

  1. From: billr@saab.CNA.TEK.COM (Bill Randle)
  2. Newsgroups: comp.sources.misc
  3. Subject: v17i097:  calentool - day/week/month/year-at-a-glance SunView tool, Part16/23
  4. Message-ID: <1991Apr6.024135.17459@sparky.IMD.Sterling.COM>
  5. Date: 6 Apr 91 02:41:35 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: fe100b7b 369923fe 9ed17a2d 6bcfe184
  8.  
  9. Submitted-by: Bill Randle <billr@saab.CNA.TEK.COM>
  10. Posting-number: Volume 17, Issue 97
  11. Archive-name: calentool/part16
  12.  
  13. #! /bin/sh
  14. # This is a shell archive.  Remove anything before this line, then unpack
  15. # it by saving it into a file and typing "sh file".  To overwrite existing
  16. # files, type "sh file -c".  You can also feed this as standard input via
  17. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  18. # will see the following message at the end:
  19. #        "End of archive 16 (of 23)."
  20. # Contents:  ct.h dates/celtic dates/sports month2ct.c utils.c
  21. # Wrapped by billr@saab on Thu Mar 28 08:38:27 1991
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'ct.h' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'ct.h'\"
  25. else
  26. echo shar: Extracting \"'ct.h'\" \(8475 characters\)
  27. sed "s/^X//" >'ct.h' <<'END_OF_FILE'
  28. X/*
  29. X * $Header: ct.h,v 2.5 91/03/27 16:45:12 billr Exp $
  30. X */
  31. X/*
  32. X * ct.h - header file for calentool
  33. X *
  34. X * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller@sun.com>
  35. X *
  36. X * Original source Copyright (C) 1987, Sun Microsystems, Inc.
  37. X *    All Rights Reserved
  38. X * Permission is hereby granted to use and modify this program in source
  39. X * or binary form as long as it is not sold for profit and this copyright
  40. X * notice remains intact.
  41. X *
  42. X *
  43. X * Changes/additions by: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
  44. X *
  45. X * Changes and additions Copyright (C) 1988, 1989, 1991 Tektronix, Inc.
  46. X *    All Rights Reserved
  47. X * Permission is hereby granted to use and modify the modifications in source
  48. X * or binary form as long as they are not sold for profit and this copyright
  49. X * notice remains intact.
  50. X */
  51. X
  52. X/*
  53. X * If calentool is too big and you want a stripped-down version
  54. X * define some or all of these here or in the Makefile. Combined,
  55. X * they save ~100K bytes for a statically linked object.
  56. X */
  57. X#define NO_PRINTER        /* exclude printer support code */
  58. X/*#define NO_HOLIDAYS        /* exclude holiday checking code */
  59. X/*#define NO_SUN_MOON        /* exclude Sun/Moon data frames */
  60. X
  61. X/* ignore several things for calencheck program */
  62. X#ifdef CALENCHECK
  63. X#    define NO_PRINTER
  64. X#    define NO_HOLIDAYS
  65. X#    define NO_SUN_MOON
  66. X#    define NOTOOL
  67. X#endif
  68. X
  69. X/* directory for date/event files */
  70. X#ifndef DATELIB_DIR
  71. X#    define DATELIB_DIR    "/usr/net/lib/calentool"
  72. X#endif
  73. X
  74. X#ifndef NO_PRINTER
  75. X/* command string for sending a file to the Postscript printer */
  76. X#    ifndef PRINT_CMD
  77. X#        define PRINT_CMD    "lpr -Plw"
  78. X#    endif
  79. X
  80. X/*#    define RASTER_ONLY    /* define this if no PostScript printer available */
  81. X#    ifndef PS_NOTE_FONT
  82. X#        define PS_NOTE_FONT     "Helvetica-Narrow"
  83. X#    endif
  84. X/*#    define LANGUAGE        /* for natural language support */
  85. X                /* see the file pcaldw.c for details */
  86. X#else
  87. X#    define RASTER_ONLY    /* do not change this line */
  88. X#endif /* NO_PRINTER */
  89. X
  90. X#ifndef MAILPROG
  91. X#    define MAILPROG        "/usr/ucb/mail"
  92. X                /* assumes -s option is available */
  93. X#endif
  94. X
  95. X/* define NR_WEEKDAYS for desired week display */
  96. X/* NR_WEEKDAYS        display   */
  97. X/*    5        Mon-Fri   */
  98. X/*    6        Mon-Sat      */
  99. X/*    7        Sun-Sat    or Mon-Sun  */
  100. X/**/
  101. X#ifndef NR_WEEKDAYS
  102. X#    define NR_WEEKDAYS    5
  103. X#endif
  104. X#ifndef MON_FIRST
  105. X#    define MON_FIRST    0    /* 0=Sun-Sat, 1=Mon-Sun */
  106. X#endif
  107. X
  108. X#ifndef START_HOUR
  109. X#    define START_HOUR    8    /* 8am */
  110. X#endif                    /*  to */
  111. X#ifndef END_HOUR
  112. X#    define END_HOUR        18    /* 6pm */
  113. X#endif
  114. X#ifndef HOUR_24
  115. X#    define HOUR_24        0    /* 0=12hr time, 1=24hr time */
  116. X#endif
  117. X#ifndef DAY_FIRST
  118. X#    define DAY_FIRST    0    /* 0=M/D/Y, 1=D/M/Y */
  119. X#endif
  120. X
  121. X#ifndef START_YEAR
  122. X#    define START_YEAR    90
  123. X#endif
  124. X#ifndef NR_YEARS
  125. X#    define NR_YEARS        5    /* number of years in menu */
  126. X#endif
  127. X
  128. X#ifndef N_NOTESLOTS
  129. X#    define N_NOTESLOTS    10    /* number of slots for notes */
  130. X#endif
  131. X
  132. X#ifndef UPDATE_RATE
  133. X#    define UPDATE_RATE    "second"    /* update time */
  134. X#endif                     /* options are "second" & "minute" */
  135. X#define TIME_OUT    2        /* check appts every 5 minutes */
  136. X
  137. X/*
  138. X * APPT_CHECK_LIMIT is typically either "n_tslots"
  139. X * or "n_slots" depending on whether we include the
  140. X * notes section when indicating that we still have
  141. X * appts today.
  142. X */
  143. X#ifndef APPT_CHECK_LIMIT
  144. X#    define APPT_CHECK_LIMIT    n_tslots
  145. X#endif
  146. X
  147. X/*********************************************************************/
  148. X/* Nothing below here should need to be changed (typically)          */
  149. X/*********************************************************************/
  150. X
  151. X#ifndef TRUE
  152. X#    define TRUE    1
  153. X#endif
  154. X#ifndef FALSE
  155. X#    define FALSE    0
  156. X#endif
  157. X
  158. X#define MAX_FUTURE_ENTRIES    32    /* number of appts displayed in popup window */
  159. X
  160. X/* Dimensions of 30-minute week slot.
  161. X * Message size determines width - everything else keyed
  162. X * off font size and message size
  163. X */
  164. X#define WEEK_MESSAGE_SIZE    12
  165. X
  166. X#define MAX_INCLUDE_NESTING    4    /* number of allowed include files */
  167. X
  168. X#define DISPLAYING_DAY          1       /* Defs for state of main */
  169. X#define DISPLAYING_WEEK         2    /* subwindow (mainsw_state) */
  170. X#define DISPLAYING_MONTH        3
  171. X#define DISPLAYING_YEAR         4
  172. X
  173. X#define BACKSPACE               8    /* editing chars */
  174. X#define CTRL_R                  18
  175. X#define CTRL_U                  21
  176. X#define CTRL_W                  23
  177. X#define DEL                     127
  178. X
  179. X#define NONE            0
  180. X#define DAY            1    /* Defs for "selected_type" (type of */
  181. X#define WEEK            2    /* object selected by month click). */
  182. X#define MONTH            3
  183. X
  184. X#define JUSTIFY_LEFT    0        /* text justification in day slot */
  185. X#define JUSTIFY_RIGHT    1
  186. X#define JUSTIFY_INDEX    2
  187. X
  188. X#define FOUND_SLOT    1        /* event tags for day display */
  189. X#define FOUND_MORE    2
  190. X#define FOUND_LARROW    3
  191. X#define FOUND_RARROW    4
  192. X
  193. X#define MMODIFY        1        /* order of entries in day menu */
  194. X#define MCUT        2
  195. X#define MPASTE        3
  196. X#define MCOPY        4
  197. X#define MDELETE        5
  198. X#define MUNDELETE    6
  199. X
  200. X#define PR_DEFAULT    0        /* print options */
  201. X#define PR_ASCII    1
  202. X#define PR_POSTSCRIPT    2
  203. X#define PR_RASTER    3
  204. X
  205. X#define SUN        0        /* days of the week */
  206. X#define MON        1
  207. X#define TUE        2
  208. X#define WED        3
  209. X#define THU        4
  210. X#define FRI        5
  211. X#define SAT        6
  212. X
  213. X#define JAN        0        /* selected months */
  214. X#define FEB        1
  215. X#define DEC        11
  216. X
  217. X#define ALL_YEARS    0x1        /* flags for special case appts */
  218. X#define ALL_MONTHS    0x2
  219. X#define ALL_DAYS    0x4
  220. X#define REPEAT        0x8
  221. X    /* check for any repeating type appt */
  222. X#    define Repeating(d)    ((d)&(ALL_YEARS|ALL_MONTHS|ALL_DAYS|REPEAT|EVERY_MON_FRI))
  223. X#define A_COMMENT    0x10
  224. X#define EVERY_SUN    0x20
  225. X#define EVERY_MON    0x40
  226. X#define EVERY_TUE    0x60
  227. X#define EVERY_WED    0x80
  228. X#define EVERY_THU    0xa0
  229. X#define EVERY_FRI    0xc0
  230. X#define EVERY_SAT    0xe0
  231. X#define    EVERY_SOMEDAY    0xe0
  232. X    /* convert flag value to day-of-week number */
  233. X#    define Pickday(d)    ((((d)&EVERY_SOMEDAY)>>5)-1)    
  234. X    /* convert day of week to flag value */
  235. X#    define Setday(d)    (((d)+1)<<5)
  236. X#define LOOKAHEAD    0x100
  237. X#define READONLY    0x200
  238. X#define A_NOTE        0x400
  239. X#define MARKED        0x800    /* don't show in month/year display */
  240. X#define MARKED_NOTE    0xc00
  241. X#define DELETED        0x1000    /* don't show the appt that matches this */
  242. X#define RUN        0x2000
  243. X#define EVERY_MON_FRI    0x4000
  244. X
  245. X/* format of repeat field for every_someday type appts */
  246. X#define WEEK1        0x1
  247. X#define WEEK2        0x2
  248. X#define WEEK3        0x4
  249. X#define WEEK4        0x8
  250. X#define WEEK5        0x10
  251. X#define ALL_WEEKS    0x1f
  252. X#define LAST_WEEK    0x20
  253. X#define WEEK_LIMIT    0x3f
  254. X
  255. X/* error reporting flags */
  256. X#define NON_FATAL    0
  257. X#define FATAL        1
  258. X
  259. X/* icon identifiers */
  260. X#define STD_ICON    0        /* flags for icon currently displayed */
  261. X#define REV_ICON    1
  262. X#define NA_ICON        2
  263. X
  264. X/* arguments to print_apts() */
  265. X#define PRI_DAY            1
  266. X#define PRI_WEEK        2
  267. X#define PRI_MONTH        3
  268. X#define PRI_XNOTES        4
  269. X#define PRI_DAY_XNOTES        (PRI_DAY|PRI_XNOTES)
  270. X#define PRI_WEEK_XNOTES        (PRI_WEEK|PRI_XNOTES)
  271. X#define PRI_MONTH_XNOTES     (PRI_MONTH|PRI_XNOTES)
  272. X#define DST_STDOUT        1
  273. X#define DST_MAIL        2
  274. X
  275. X/* return codes from get_day_appts() */
  276. X#define NO_ENTRIES    0
  277. X#define SOME_APPTS    1
  278. X#define SOME_NOTES    2
  279. X#define SOME_MKNOTES    4
  280. X#define SOME_FUTURES    8
  281. X
  282. X/* header line in appts file implies one-based entries and 99 memo flag */
  283. X#define HEADER        "# CalenTool V2.2 - DO NOT REMOVE THIS LINE\n"
  284. X#define OHEADER        "# CalenTool V2 - DO NOT REMOVE THIS LINE\n"
  285. X
  286. X#define MAX_STRLEN    256    /* max size of strings */
  287. Xstruct appt_entry {
  288. X    /* describes an entry in the appointments file */
  289. X    int year, month, day, hour, minute, arrows;
  290. X    int repeat, lookahead, flags, sindex;
  291. X    int runlength, warn;
  292. X    char str[MAX_STRLEN];
  293. X    struct appt_entry *next;    /* ptr to next appt in list */
  294. X};                    /* NULL if last entry */
  295. X
  296. Xstruct rect_pos {
  297. X    /* location of a given rect in the canvas */
  298. X    int top, bottom, left, right;
  299. X};
  300. X
  301. Xstruct dayslot {
  302. X    /* struct for storing relevant info for 30 min day slot */
  303. X    struct rect_pos slot_pos; /* slot position in day display */
  304. X    struct rect_pos larrow_pos; /* position of left scroll arrow */
  305. X    struct rect_pos rarrow_pos; /* position of right scroll arrow */
  306. X    struct rect_pos moreb_pos; /* position of "more" button */
  307. X    int active;    /* number of appts that originate here */
  308. X    int count;    /* number of appts in this slot */
  309. X    int arrow_pos;    /* bitmap of arrow locations on screen */
  310. X    struct appt_entry *cur_appt;    /* ptr to current appt in list */
  311. X    struct appt_entry *first;    /* ptr to first appt in list */
  312. X};                    /* NULL if no entries */
  313. X
  314. Xstruct weekrect {
  315. X    /* info for week display */
  316. X    struct rect_pos wday_pos; /* screen position of this day */
  317. X    struct rect_pos moreb_pos; /* position of "more" button */
  318. X    int more;
  319. X    struct dayslot *weekslots; /* array of slots for this day */
  320. X};
  321. X
  322. Xstruct rect_limits {
  323. X    int lowx;
  324. X    int lowy;
  325. X    int highx;
  326. X    int highy;
  327. X};
  328. X
  329. Xstruct week_arrow {
  330. X    int top;
  331. X    int bottom;
  332. X    int left;
  333. X    int right;
  334. X    int active;
  335. X};
  336. END_OF_FILE
  337. if test 8475 -ne `wc -c <'ct.h'`; then
  338.     echo shar: \"'ct.h'\" unpacked with wrong size!
  339. fi
  340. # end of 'ct.h'
  341. fi
  342. if test -f 'dates/celtic' -a "${1}" != "-c" ; then 
  343.   echo shar: Will not clobber existing file \"'dates/celtic'\"
  344. else
  345. echo shar: Extracting \"'dates/celtic'\" \(541 characters\)
  346. sed "s/^X//" >'dates/celtic' <<'END_OF_FILE'
  347. X# CalenTool V2.2 - nflag=1 range=2,11 - DO NOT REMOVE THIS LINE
  348. X# $Header: celtic,v 2.3 91/03/07 16:21:04 billr Exp $
  349. X# Special days file for calentool (rel 2.1); modified from network posting by
  350. X# RPC Rodgers, UCSF, Nov. 1988
  351. X# Dates of interest to Celts
  352. X#
  353. X** 02 01 99 99 00 Oimelc (Winter purification & approach of spring)
  354. X** 05 01 99 99 00 Beltaine (Feast of sun god Bel)
  355. X** 08 01 99 99 00 Lughnasa (Feast of god Lugh, 30 day Celtic feast centers on this day)
  356. X** 11 01 99 99 00 Samhain (beginning of Celtic year, most important holiday)
  357. END_OF_FILE
  358. if test 541 -ne `wc -c <'dates/celtic'`; then
  359.     echo shar: \"'dates/celtic'\" unpacked with wrong size!
  360. fi
  361. # end of 'dates/celtic'
  362. fi
  363. if test -f 'dates/sports' -a "${1}" != "-c" ; then 
  364.   echo shar: Will not clobber existing file \"'dates/sports'\"
  365. else
  366. echo shar: Extracting \"'dates/sports'\" \(8498 characters\)
  367. sed "s/^X//" >'dates/sports' <<'END_OF_FILE'
  368. X# CalenTool V2.2 - nflag=1 range=1,12 - DO NOT REMOVE THIS LINE
  369. X# $Header: sports,v 1.2 91/03/07 16:21:32 billr Exp $
  370. X# Special dates in sports history
  371. X# Today in History dates provided by Robert Heckendorn at
  372. X# Hewlett-Packard in Fort Collins, Colorado.
  373. X# Any corrections or additions may be sent to robert@fc.hp.com
  374. X#
  375. X# Additional dates provided from ProLine's today file
  376. X#
  377. X# Converted to calentool format by Larry Virden (lwv27%cas.BITNET@CUNYVM.CUNY.Edu)
  378. X# and further edited and merged by Bill Randle (billr@saab.cna.tek.com).
  379. X#
  380. X** 01 01 99 99 00 1st Rose Bowl game held in Pasadena, California. (1902)
  381. X** 01 01 99 99 00 1st running of SF's famed "Bay to Breakers" race (7.63 miles) (1912)
  382. X** 01 01 99 99 00 All registered thoroughbred and quarter horses are "born" on this day
  383. X** 01 16 99 99 00 First college basketball game, Iowa vs Chicago (1896)
  384. X** 01 29 99 99 00 1st athletic letters given: to Univ of Chicago football team. (1904)
  385. X** 02 02 99 99 00 National Baseball League formed with 8 teams. (1876)
  386. X** 02 04 99 99 00 1st Winter Olympics held (At Lake Placid, NY). (1932)
  387. X** 02 12 99 99 00 The six cars entered in the New York to Paris road race set off on their 12116 mile race through Alaska and Russia. America won. (1908)
  388. X** 03 11 99 99 00 1st public game of basketball. (1892)
  389. X** 03 28 99 99 00 A New York judge rules that the contest between the American catamaran and the Australian monohull was not fair competition and the America's Cup was returned to the Australians (1989)
  390. X** 04 04 99 99 00 President William Howard Taft throws out the first ball of the season to a game between Washington and Philadelphia. Thus starting a tradition (1910)
  391. X** 04 04 99 99 00 Hank Aaron of Atlanta Braves ties Babe Ruth's home run record at 714 (1974)
  392. X** 04 08 99 99 00 Hammerin' Hank Aaron hits 715th home run, beats Babe Ruth's record. (1974)
  393. X** 04 11 99 99 00 Jackie Robinson breaks the color barrier in baseball when he plays for the Brooklyn Dodgers (1947)
  394. X** 04 12 99 99 00 The catcher's mask was first used in a baseball game. (1877)
  395. X** 04 14 99 99 00 President Taft starts the tradition of throwing out the 1st baseball (1910)
  396. X** 04 16 99 99 00 Bob Feller of the Cleveland Indians pitched a no-hitter on opening day of the American League season (1940)
  397. X** 04 23 99 99 00 Hank Aaron hits his first home run (1954)
  398. X** 04 28 99 99 00 Muhammad Ali (Heavyweight Champ) refused to be inducted into Army (1967)
  399. X** 05 02 99 99 00 Lou Gehrig sets record for being in most consecutive games (2130). (1939)
  400. X** 05 17 99 99 00 First Kentucky Derby held (1875)
  401. X** 05 17 99 99 00 The first Kentucky Derby was run at Churchill Downs. (1875)
  402. X** 05 25 99 99 00 Babe Ruth hits his 714th and final home run of his career (1935)
  403. X** 05 30 99 99 00 Indianapolis 500 car race run for 1st time. (1911)
  404. X** 06 01 99 99 00 Lou Gehrig starts in 1st of 2130 consecutive games, a record. (1925)
  405. X** 06 11 99 99 00 1st auto race. (1895)
  406. X** 06 12 99 99 00 The National Baseball Hall of Fame and Museum was dedicated. (1939)
  407. X** 06 12 99 99 00 the 1st baseball game is played in America (1839)
  408. X** 06 12 99 99 00 the 3rd baseball strike starts. (1981)
  409. X** 07 05 99 99 00 New York Mets defeated Atlanta Braves, 16-13, in 19 inning game that lasted 6 hours and 10 min. ending just before 4 a.m. (1985)
  410. X** 07 06 99 99 00 1st All-Star baseball game.  American League won 5-2. (1933)
  411. X** 07 11 99 99 00 Houston Astros pitcher, Nolan Ryan struck out 4000 batters. (1985)
  412. X** 07 13 99 99 00 Women first compete in Olympic games (1908)
  413. X** 07 18 99 99 00 Ty Cobb gets 4000th base hit (1927)
  414. X** 07 20 99 99 00 admission fee 1st charged to see a baseball game (50 cents). (1859)
  415. X** 07 21 99 99 00 Eddy Merckx won his first of five Tour de France victories (1969)
  416. X** 07 23 99 99 00 Greg LeMond wins his second Tour de France, beating Laurent Fignon in the final 15 mile time trial by turning a 50 second deficit into a win by 8 seconds! (1989)
  417. X** 07 29 99 99 00 King George VI opened the Olympic games in London (1948)
  418. X** 08 01 99 99 00 Adolph Hitler opened the Olympic Games in Berlin. (1936)
  419. X** 08 02 99 99 00 Several former members of the Chicago White Sox and two others were acquitted in the "Black Sox" scandal (1921)
  420. X** 08 06 99 99 00 Cy Young pitches first major league game (1890)
  421. X** 08 06 99 99 00 Gertrude Ederle of New York is the first American woman to swim the English Channel (1926)
  422. X** 08 08 99 99 00 the first America's Cup race (1870)
  423. X** 08 10 99 99 00 Pete Rose tops Stan Musial's record of 3630 hits. (1981)
  424. X** 08 20 99 99 00 Diana Nyad becomes the first woman to swim the 89 miles from the Bahamas to Florida (time: 27h 38m) (1979)
  425. X** 08 21 99 99 00 Babe Ruth hit his 600th career home run. (1931)
  426. X** 08 22 99 99 00 Althea Gibson becomes the first black tennis plaer to be accepted in competition for the national chapionship (1950)
  427. X** 08 22 99 99 00 the yacht America wins in race against 14 yachts of England in the first America Cup sailing race (1851)
  428. X** 08 25 99 99 00 Captain Matthew Webb becomes the first person to swim the English Channel, travelling from Dover to Calais in 22 hours (1875)
  429. X** 08 26 99 99 00 The summer Olympics opened in Munich, West Germany. (1972)
  430. X** 08 29 99 99 00 Lou Brock eclipsed the stolen-bases record as he stole two bases against the San Diego Padres, bring his total to 893 (1977)
  431. X** 08 31 99 99 00 The 1st U.S. tennis championships were played in Newport, R.I. (1882)
  432. X** 09 01 99 99 00 Bobby Fischer defeats Boris Spassky in World Chess Match (1972)
  433. X** 09 04 99 99 00 Mark Spitz becomes first man to win 7 gold medals in the Olympics (1972)
  434. X** 09 06 99 99 00 Czechoslovakian tennis star, Martina Navratilova, requested political asylum while in New York for the U.S. open (1975)
  435. X** 09 07 99 99 00 ESPN, the sports cable network, makes its debut (1979)
  436. X** 09 13 99 99 00 Fay Vincent was named commissioner of Major League Baseball. (1989)
  437. X** 09 13 99 99 00 The ladies Professional Golf Association of America was formed. (1949)
  438. X** 09 17 99 99 00 The American Professional Football Association was formed. (1920)
  439. X** 09 23 99 99 00 1st closed circuit pay-TV telecast of a sports event. (1952)
  440. X** 09 23 99 99 00 New York Knickerbockers becomes first U.S. Baseball club (1845)
  441. X** 09 24 99 99 00 Babe Ruth makes his farewell regular baseball player for the New York Yankees (1934)
  442. X** 09 26 99 99 00 Australia II won the America's Cup yacht race. (1983)
  443. X** 09 28 99 99 00 eight members of the Chicago White Sox were indicted for allegedly throwing the 1919 World Series against the Cincinnati Reds in the "Black Sox" scandal (1920)
  444. X** 09 29 99 99 00 The 1st night football game was played in Mansfield, Pennsylvania. (1892)
  445. X** 10 01 99 99 00 1st World Series starts between the National & American Leagues (1903)
  446. X** 10 07 99 99 00 Georgia Tech beat Cumberland University 222-0 in a football game. (1916)
  447. X** 10 07 99 99 00 Lynnette Woodward becomes the first female Harlem Globetrotter (1985)
  448. X** 10 12 99 99 00 The race horse Man O'War's last race (1920)
  449. X** 10 13 99 99 00 The International Olympic committee announced it would restore the two gold medals it had taken from Jim Thorpe (1982)
  450. X** 10 13 99 99 00 The first world series game is played (1903)
  451. X** 10 18 99 99 00 Connie Mack, the "Grand Old Man" of major league baseball, announced he would retire as manager of the Philadelphia Athletics (1950)
  452. X** 10 18 99 99 00 the Ivy League establishes rules for college football. (1873)
  453. X** 10 19 99 99 00 Jim Ochowicz, manager of the Seven-Eleven cycling team announced that the team will be sponsored by Motorola (1990)
  454. X** 11 01 99 99 00 Notre Dame's football team upsets Army 35-13 in a game that help popularize the forward pass (1913)
  455. X** 11 06 99 99 00 the first formal intercollegiate football game played (Rutgers 6 - Princeton 4) (1869)
  456. X** 11 25 99 99 00 Radio station WTAW of college station, Texas, broadcast the first play-by-play description of a football game (1920)
  457. X** 11 28 99 99 00 The first automobile race was held from Chicago to Waukegan through the snow; 6 cars, 55 miles, winner averaged 7 MPH (1895)
  458. X** 11 29 99 99 00 1st Army-Navy football game.  Score: Navy 25, Army 0. (1890)
  459. X** 12 04 99 99 00 Numbers first appear on football uniforms (1908)
  460. X** 12 15 99 99 00 James Naismith, a Canadian, invents basketball, while working at the Y.M.C.A. College at Springfield, Massachusetts (1891)
  461. X** 12 17 99 99 00 1st professional football game: Chicago Bears vs. NY Giants. (1933)
  462. X** 12 26 99 99 00 1st East-West football game at Ewing Park before 25,000 fans. (1925)
  463. END_OF_FILE
  464. if test 8498 -ne `wc -c <'dates/sports'`; then
  465.     echo shar: \"'dates/sports'\" unpacked with wrong size!
  466. fi
  467. # end of 'dates/sports'
  468. fi
  469. if test -f 'month2ct.c' -a "${1}" != "-c" ; then 
  470.   echo shar: Will not clobber existing file \"'month2ct.c'\"
  471. else
  472. echo shar: Extracting \"'month2ct.c'\" \(4022 characters\)
  473. sed "s/^X//" >'month2ct.c' <<'END_OF_FILE'
  474. X/*
  475. X * $Header: month2ct.c,v 2.2 91/02/01 12:20:10 billr Exp $
  476. X */
  477. X/*
  478. X * month2ct - convert month schedule files to calentool style files
  479. X *
  480. X * Author: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
  481. X *
  482. X * Copyright (C) 1989, 1991 Tektronix, Inc.  All Rights Reserved
  483. X *
  484. X * Permission is hereby granted to use and modify this code in source
  485. X * or binary form as long as it is not sold for profit and this copyright
  486. X * notice remains intact.
  487. X */
  488. X
  489. X#include "month.h"
  490. X#include "ct.h"
  491. X#include <stdio.h>
  492. X
  493. Xstruct appt_entry appt;
  494. Xstruct event_rec events;
  495. XFILE *fp;
  496. Xchar filename[128];
  497. Xchar *dir, *getenv();
  498. X
  499. Xmain(argc, argv)
  500. Xint argc;
  501. Xchar *argv[];
  502. X{
  503. X    if (argc > 1)
  504. X        dir = argv[1];
  505. X    else {
  506. X        strcpy(filename, getenv("HOME"));
  507. X        dir = filename;
  508. X    }
  509. X
  510. X    if (read_schedule(dir, READ_ONLY)) {
  511. X        fprintf(stderr, "no reminders read from %s/.month\n", dir);
  512. X        exit(1);
  513. X    }
  514. X    strcpy(filename, getenv("HOME"));
  515. X    strcat(filename, "/.appointments");
  516. X    if ((fp = fopen(filename, "w")) == NULL) {
  517. X        fprintf(stderr, "can't open .appointments file for writing\n");
  518. X        exit(1);
  519. X    }
  520. X    write_ct_file();
  521. X}
  522. X
  523. X/*
  524. X * write out the new .appointments file
  525. X */
  526. Xwrite_ct_file()
  527. X{
  528. X    struct event_rec *evt;
  529. X    int length, oflags, i;
  530. X
  531. X    evt = &events;
  532. X    fputs(HEADER, fp);
  533. X    /* first event is empty */
  534. X    evt = evt->next_event;
  535. X    while (evt) {
  536. X        /* DEBUG
  537. X        fprintf(stderr,"evt struct:\n  mly=%d, yly=%d, evry=%d\n  nth=%d, last=%d, nthon=%d\n  str=%s\n",
  538. X            evt->monthly, evt->yearly, evt->every, evt->nth, evt->last, evt->nth_is_on, evt->event_string);
  539. X        */
  540. X        appt.flags = appt.repeat = appt.lookahead = 0;
  541. X        appt.warn = 10;  /* default */
  542. X        appt.year = evt->start_date.year - 1900;
  543. X        appt.month = evt->start_date.month - 1;
  544. X        appt.day = evt->start_date.day;
  545. X        strcpy(appt.str, evt->event_string);
  546. X        if (evt->monthly)
  547. X            appt.flags |= ALL_MONTHS;
  548. X        if (evt->yearly)
  549. X            appt.flags |= ALL_YEARS;
  550. X        appt.hour = evt->start_time.hour;
  551. X        appt.minute = evt->start_time.minute;
  552. X        if (appt.hour > 23 || appt.hour < 0 || appt.minute > 59 || appt.minute < 0)
  553. X            appt.flags |= A_NOTE;
  554. X        if (appt.minute < 15)
  555. X            appt.minute = 0;
  556. X        else if (appt.minute < 45)
  557. X            appt.minute = 30;
  558. X        else {
  559. X            appt.minute = 0;
  560. X            appt.hour++;
  561. X        }
  562. X        length = evt->duration.hour * 60 + evt->duration.minute;
  563. X        appt.arrows = length / 30 - 1;
  564. X        if (appt.arrows < 0)
  565. X            appt.arrows = 0;
  566. X        if (evt->anti)
  567. X            appt.flags |= DELETED;
  568. X        if (evt->warning.hour >= 24)
  569. X            appt.lookahead = evt->warning.hour / 24;
  570. X        else
  571. X            appt.warn = evt->warning.hour * 60 + evt->warning.minute;
  572. X        if (evt->until) {
  573. X            fprintf(stderr, "this appointment runs more than 1 day,\n");
  574. X            fprintf(stderr, "modify the calentool entry after conversion:\n");
  575. X            fprintf(stderr, "start date (m/d/y): %d/%d/%d, ",
  576. X              evt->start_date.month, evt->start_date.day,
  577. X              evt->start_date.year);
  578. X            fprintf(stderr, "start time: %d:%d, ", evt->start_time.hour,
  579. X              evt->start_time.minute);
  580. X            fprintf(stderr, "runs until (m/d/y): %d/%d/%d\n",
  581. X              evt->until_date.month, evt->until_date.day,
  582. X              evt->until_date.year);
  583. X        }
  584. X        if (evt->every) {
  585. X            /* event occurs on an every something */
  586. X            appt.flags |= REPEAT;
  587. X            if (evt->last)
  588. X                appt.repeat = LAST_WEEK;
  589. X            else if (evt->nth_is_on)
  590. X                appt.repeat = 1<<(evt->nth_is_on-1);
  591. X            else
  592. X                appt.repeat = ALL_WEEKS;
  593. X            oflags = appt.flags;
  594. X            /* check for mon-fri */
  595. X            if (!evt->smtwtfs[0] && !evt->smtwtfs[6] &&
  596. X                evt->smtwtfs[1] && evt->smtwtfs[2] &&
  597. X                evt->smtwtfs[3] && evt->smtwtfs[4] &&
  598. X                evt->smtwtfs[5]) {
  599. X                appt.flags |= EVERY_MON_FRI;
  600. X                if (put_aentry(fp, &appt)) {
  601. X                    fprintf(stderr,
  602. X                      "error writing .appointments file\n");
  603. X                    return;
  604. X                }
  605. X            } else
  606. X                for (i=0; i<7; i++) {
  607. X                    if (evt->smtwtfs[i]) {
  608. X                        appt.flags = oflags | Setday(i);
  609. X                        if (put_aentry(fp, &appt)) {
  610. X                            fprintf(stderr,
  611. X                              "error writing .appointments file\n");
  612. X                            return;
  613. X                        }
  614. X                    }
  615. X                }
  616. X        } else
  617. X            if (put_aentry(fp, &appt)) {
  618. X                fprintf(stderr, "error writing .appointments file\n");
  619. X                return;
  620. X            }
  621. X        fputs("\n", fp);
  622. X        evt = evt->next_event;
  623. X    }
  624. X}
  625. END_OF_FILE
  626. if test 4022 -ne `wc -c <'month2ct.c'`; then
  627.     echo shar: \"'month2ct.c'\" unpacked with wrong size!
  628. fi
  629. # end of 'month2ct.c'
  630. fi
  631. if test -f 'utils.c' -a "${1}" != "-c" ; then 
  632.   echo shar: Will not clobber existing file \"'utils.c'\"
  633. else
  634. echo shar: Extracting \"'utils.c'\" \(29701 characters\)
  635. sed "s/^X//" >'utils.c' <<'END_OF_FILE'
  636. X/*
  637. X * $Header: utils.c,v 2.8 91/03/27 16:46:39 billr Exp $
  638. X */
  639. X/*
  640. X * utils.c
  641. X *
  642. X * calentool - a year/month/week/day-at-a-glance calendar for Sun workstations.
  643. X *
  644. X * Author: Philip Heller, Sun Microsystems. Inc. <terrapin!heller@sun.com>
  645. X *
  646. X * Original source Copyright (C) 1987, Sun Microsystems, Inc.
  647. X *    All Rights Reserved
  648. X * Permission is hereby granted to use and modify this program in source
  649. X * or binary form as long as it is not sold for profit and this copyright
  650. X * notice remains intact.
  651. X *
  652. X *
  653. X * Changes/additions by: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
  654. X *
  655. X * Changes and additions Copyright (C) 1988, 1989, 1991 Tektronix, Inc.
  656. X *    All Rights Reserved
  657. X * Permission is hereby granted to use and modify the modifications in source
  658. X * or binary form as long as they are not sold for profit and this copyright
  659. X * notice remains intact.
  660. X * Modified parse_date to allow +nnn and -nnn syntax for dates relative to the
  661. X * current date.  Peter Marshall <peter.marshall@uwo.ca>. 1989-09-19.
  662. X */
  663. X/********************************************
  664. X *                        *
  665. X *              Utility routines.        *
  666. X *                        *
  667. X ********************************************/
  668. X
  669. X
  670. X
  671. X#include "ct.h"
  672. X#include <stdio.h>
  673. X#ifndef NOTOOL
  674. X#include <suntool/sunview.h>
  675. X#include <suntool/canvas.h>
  676. X#endif  /* NOTOOL */
  677. X#include <ctype.h>
  678. X#include <sys/types.h>
  679. X#include <sys/time.h>
  680. X#include <sys/file.h>
  681. X#include <sys/stat.h>
  682. X#include <sys/errno.h>
  683. X
  684. X
  685. Xextern struct tm today, current;
  686. Xextern struct tm First;
  687. Xextern int day_is_open, read_only;
  688. Xextern int n_slots;
  689. Xextern struct dayslot *slots;
  690. Xextern char apts_pathname[], tmpapts_pathname[];
  691. Xextern char *progname;
  692. Xextern int one_based, version2, new_entry;
  693. Xextern char apts_dir[], lib_dir[];
  694. Xextern int include_old, save_old, expire_days;
  695. X#ifndef NOTOOL
  696. Xextern Frame frame;
  697. Xextern Canvas canvas;
  698. Xextern Pixwin *main_pixwin;
  699. Xextern int mainsw_state;
  700. Xextern Pixfont *font, *sfont;
  701. Xextern Frame prompt_frame;
  702. Xextern int update_interval;
  703. Xextern int monday_first, hour24, day_first;
  704. X#endif  /* NOTOOL */
  705. Xextern int week_ofs;
  706. Xextern int errno;
  707. X
  708. Xchar inbuf[512], strbuf[256], errbuf[128];
  709. Xchar clockstr[32];
  710. Xstatic int include_level = 0;
  711. Xstatic int log_to_console;
  712. Xchar *daynames[] = {"Sunday","Monday","Tuesday","Wednesday",
  713. X               "Thursday","Friday","Saturday"};
  714. Xchar *monthnames[] = {"January","February","March","April",
  715. X                 "May","June","July","August",
  716. X                 "September","October","November","December"};
  717. Xchar *smonthnames[] = {"Jan","Feb","Mar","Apr",
  718. X                 "May","Jun","Jul","Aug",
  719. X                 "Sep","Oct","Nov","Dec"};
  720. Xchar *dayname[8] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA", "MF"};
  721. X
  722. Xextern char *strcpy(), *strcat();
  723. X
  724. X/*
  725. X * sets "today" and current time
  726. X */
  727. Xvoid
  728. Xget_today()
  729. X{
  730. X    struct tm *tm;
  731. X    struct timeval tv;
  732. X    char timstr[16];
  733. X
  734. X    gettimeofday(&tv, 0);
  735. X    tm = localtime(&tv.tv_sec);
  736. X
  737. X    today = *tm;
  738. X
  739. X#ifndef CALENCHECK
  740. X    if (day_first)
  741. X        sprintf(clockstr, "%3.3s %d %s %d, ", daynames[today.tm_wday],
  742. X            today.tm_mday, smonthnames[today.tm_mon], today.tm_year+1900);
  743. X    else
  744. X        sprintf(clockstr, "%3.3s %s %d %d, ", daynames[today.tm_wday],
  745. X            smonthnames[today.tm_mon], today.tm_mday, today.tm_year+1900);
  746. X    if (update_interval >= 60)
  747. X        sprintf(timstr, "%02d:%02d", today.tm_hour, today.tm_min);
  748. X    else
  749. X        sprintf(timstr, "%02d:%02d:%02d", today.tm_hour, today.tm_min, today.tm_sec);
  750. X    if (!hour24) {
  751. X        /* display am/pm for 12-hour time */
  752. X        if (today.tm_hour > 12) {
  753. X            strcat(timstr, "pm");
  754. X            timstr[0] = ((today.tm_hour - 12) / 10) + '0';
  755. X            timstr[1] = ((today.tm_hour - 12) % 10) + '0';
  756. X        } else if (today.tm_hour == 12) {
  757. X            strcat(timstr, "pm");
  758. X        } else {
  759. X            strcat(timstr, "am");
  760. X        }
  761. X        if (timstr[0] == '0')
  762. X            timstr[0] = ' ';
  763. X    }
  764. X    strcat(clockstr, timstr);
  765. X#endif  /* CALENCHECK */
  766. X}
  767. X
  768. X/*
  769. X *    Reset some values in current tm structure. Year, month and
  770. X *    day-of-month are valid but day and/or month may be < 0 or
  771. X *    greater than the maximum value, in which case they are adjusted
  772. X *    accordingly. Day-of-year and day-of-week are then recalculated.
  773. X */
  774. Xvoid
  775. Xfix_current_day()
  776. X{
  777. X    int month, totdays = 0;
  778. X    struct tm from, to;
  779. X
  780. X    if (current.tm_mon < JAN) {
  781. X        current.tm_mon = DEC;
  782. X        current.tm_year--;
  783. X    } else if (current.tm_mon > DEC) {
  784. X        current.tm_mon = JAN;
  785. X        current.tm_year++;
  786. X    }
  787. X    if (current.tm_mday < 1) {
  788. X        current.tm_mon--;
  789. X        if (current.tm_mon < JAN) {
  790. X            current.tm_mon = DEC;
  791. X            current.tm_year--;
  792. X        }
  793. X        current.tm_mday += monthlength(current.tm_mon);
  794. X    } else if (current.tm_mday > monthlength(current.tm_mon)) {
  795. X        current.tm_mday -= monthlength(current.tm_mon);
  796. X        current.tm_mon++;
  797. X        if (current.tm_mon > DEC) {
  798. X            current.tm_mon = JAN;
  799. X            current.tm_year++;
  800. X        }
  801. X    }
  802. X    current.tm_yday = day_of_year((double)current.tm_mday, current.tm_mon+1, current.tm_year+1900) - 1;
  803. X    current.tm_wday = get_day_of_week((double)current.tm_mday, current.tm_mon+1, current.tm_year+1900);
  804. X}
  805. X
  806. X/*
  807. X * Compares two sets of year/month/day.  Returns -1 if the first is earlier than
  808. X * the second, +1 if later, 0 if they are the same.
  809. X */
  810. Xymd_compare(day0, day1)
  811. Xstruct tm day0, day1;
  812. X{
  813. X        if (day0.tm_year > day1.tm_year) return(1);
  814. X        if (day0.tm_year < day1.tm_year) return(-1);
  815. X        if (day0.tm_mon > day1.tm_mon) return(1);
  816. X        if (day0.tm_mon < day1.tm_mon) return(-1);
  817. X        if (day0.tm_mday > day1.tm_mday) return(1);
  818. X        if (day0.tm_mday < day1.tm_mday) return(-1);
  819. X        return(0);
  820. X}
  821. X
  822. X/*
  823. X * Compares two sets of year/month/day.  Returns -1 if the first is earlier than
  824. X * the second, +1 if later, 0 if they are the same.  Similar to
  825. X * ymd_compare() only compares given date to date of an appt entry.
  826. X */
  827. Xymd2_compare(day0, aday)
  828. Xstruct tm *day0;
  829. Xstruct appt_entry *aday;
  830. X{
  831. X        if (day0->tm_year > aday->year) return(1);
  832. X        if (day0->tm_year < aday->year) return(-1);
  833. X        if (day0->tm_mon > aday->month) return(1);
  834. X        if (day0->tm_mon < aday->month) return(-1);
  835. X        if (day0->tm_mday > aday->day) return(1);
  836. X        if (day0->tm_mday < aday->day) return(-1);
  837. X        return(0);
  838. X}
  839. X
  840. Xint
  841. Xmonthlength(month)
  842. Xint    month;
  843. X{
  844. X    static int    monthlengths[] = {31,28,31,30,31,30,31,31,30,31,30,31};
  845. X
  846. X    if (month == FEB && (length_of_year(current.tm_year + 1900) == 366))
  847. X        return(29);
  848. X    else
  849. X        return(monthlengths[month]);
  850. X}
  851. X
  852. X/*
  853. X *
  854. X * Append data from active timeslots to end of "tmp.appointments"
  855. X * file, then copy "tmp.appointments" to "appointments".  Note that
  856. X * when we opened the current day we filtered "appointments":
  857. X * all items that applied to the current day were displayed and
  858. X * stored in slots; all others were copied to "tmp.appointments".
  859. X * So by now "tmp.appointments" contains no entries for the
  860. X * current day.
  861. X * As an optimization, if nothing changed in the day then the
  862. X * original appointments file is left unchanged.
  863. X *
  864. X */
  865. X
  866. Xclose_day()
  867. X{
  868. X        int i, j;
  869. X        FILE *f;
  870. X    struct stat sbuf;
  871. X    struct appt_entry *aptr, *optr;
  872. X
  873. X    if (read_only || !new_entry) {
  874. X        new_entry = 0;
  875. X        day_is_open = FALSE;
  876. X        return(0);
  877. X    }
  878. X
  879. X#ifndef CALENCHECK
  880. X    f = fopen(tmpapts_pathname, "a+");
  881. X    if (f == NULL) {
  882. X        err_rpt("can't open temp file for appending", NON_FATAL);
  883. X        day_is_open = FALSE;
  884. X        return(1);
  885. X    }
  886. X    
  887. X    for (i=0; i<n_slots; i++) {
  888. X                if (slots[i].first != NULL) {
  889. X            aptr = slots[i].first;
  890. X            if (put_aentry(f, aptr))
  891. X                /* write error */
  892. X                break;
  893. X            optr = aptr;
  894. X            while (aptr = aptr->next) {
  895. X                free(optr);
  896. X                if (put_aentry(f, aptr))
  897. X                    /* write error */
  898. X                    break;
  899. X                optr = aptr;
  900. X            }
  901. X            free(optr);
  902. X        }
  903. X        }
  904. X    if (ferror(f))
  905. X        err_rpt("write on temp file failed", FATAL);
  906. X        fclose(f);
  907. X    new_entry = 0;
  908. X    day_is_open = FALSE;
  909. X    /* don't rename zero length files */
  910. X    stat(tmpapts_pathname, &sbuf);
  911. X    if (sbuf.st_size == (off_t) 0)
  912. X        return(1);
  913. X    xrename(tmpapts_pathname, apts_pathname);
  914. X#endif  /* CALENCHECK */
  915. X    return(0);
  916. X}
  917. X
  918. X/*
  919. X * get entry from appointments file
  920. X */
  921. Xget_aentry(apts_file, appt, noInclude, noUmkNotes, target)
  922. XFILE *apts_file;
  923. Xstruct appt_entry *appt;
  924. Xint noInclude;
  925. Xint noUmkNotes;
  926. Xint target;
  927. X{
  928. X    char *ptr, *str;
  929. X    char *fgets(), *index();
  930. X    char *incl_ptr, incl_buf[128], wday[3];
  931. X    int i, lib, parse_options, nodata = 1;
  932. X    int n, nflag, lrange, hrange;
  933. X    struct stat sbuf;
  934. X    static FILE *include[MAX_INCLUDE_NESTING];
  935. X
  936. X    appt->flags = appt->repeat = appt->lookahead = 0;
  937. X    appt->sindex = 0;
  938. X    appt->runlength = 0;
  939. X    appt->warn = 10;
  940. X    appt->next = NULL;
  941. X    /* If noInclude is set then don't follow include files, i.e.
  942. X     * treat #include directives as comments. This is useful for
  943. X     * copying the appts file.
  944. X     */
  945. X    while (nodata) {
  946. X        if (include_level) {
  947. X            if (fgets(inbuf, 512, include[include_level-1]) == NULL) {
  948. X                /* end of include file - get next entry
  949. X                 * from previous level of nesting
  950. X                 */
  951. X                unwind:
  952. X                fclose(include[include_level-1]);
  953. X                include_level--;
  954. X            } else {
  955. X                /* don't modify stuff from include files */
  956. X                appt->flags |= READONLY;
  957. X                nodata = 0;    /* still data in file */
  958. X            }
  959. X        } else {
  960. X            if (fgets(inbuf, 512, apts_file) == NULL)
  961. X                return(EOF);
  962. X            else
  963. X                nodata = 0;    /* still data in file */
  964. X        }
  965. X    }
  966. X    ptr = inbuf;
  967. X    if (noInclude && *ptr == '#') {
  968. X        appt->flags |= A_COMMENT;
  969. X        return(0);
  970. X    }
  971. X    if (*ptr == '#') {
  972. X        if (!include_level && (!strcmp(inbuf, OHEADER) ||
  973. X            !strncmp(inbuf, HEADER, 18))) {
  974. X            /* first line in base file read */
  975. X            if (include_old && (First.tm_year <= today.tm_year)) {
  976. X                /* read in old include file (if it exists) */
  977. X                /* prepend directory info */
  978. X                sprintf(incl_buf, "%s.%02d",
  979. X                    apts_pathname, First.tm_year);
  980. X                if (!stat(incl_buf, &sbuf)) {
  981. X                    if ((include[include_level] = fopen(incl_buf, "r")) == NULL) {
  982. X                        strcpy(errbuf, "can't open include file <");
  983. X                        strcat(errbuf, incl_buf);
  984. X                        strcat(errbuf, "> (ignored)");
  985. X                        err_rpt(errbuf, NON_FATAL);
  986. X                    } else
  987. X                        include_level++;
  988. X                }
  989. X            }
  990. X            if (!strcmp(inbuf, OHEADER))
  991. X                /* substitute new header format */
  992. X                strcpy(inbuf, HEADER);
  993. X        } else if (!strncmp(inbuf, HEADER, 18)) {
  994. X            /* found a ver 2.2 header - get statistics */
  995. X            n = sscanf(inbuf, "%*[^-]- nflag=%d range=%d,%d",
  996. X                &nflag, &lrange, &hrange);
  997. X            if (n == 3 && include_level) {
  998. X                /* proper match found */
  999. X                if (noUmkNotes && nflag)
  1000. X                    goto unwind;
  1001. X                if (target && (target < lrange || target > hrange))
  1002. X                    goto unwind;
  1003. X            }
  1004. X        } else if (!strncmp(inbuf, "#include", 8)) {
  1005. X            /* include file */
  1006. X            if (include_level > MAX_INCLUDE_NESTING) {
  1007. X                err_rpt("include files nested too deep (ignored)", NON_FATAL);
  1008. X                appt->flags |= A_COMMENT;
  1009. X                return(0);
  1010. X            }
  1011. X            incl_ptr = strbuf;
  1012. X            if ((ptr = index(inbuf, '"')) == NULL)
  1013. X
  1014. X                if ((ptr = index(inbuf, '<')) == NULL) {
  1015. X                    err_rpt("missing '\"' or '<' in include file spec", NON_FATAL);
  1016. X                    appt->flags |= A_COMMENT;
  1017. X                    return(0);
  1018. X                } else {
  1019. X                    lib = 1;
  1020. X                }
  1021. X            else
  1022. X                lib = 0;
  1023. X            ptr++;
  1024. X            while (*ptr && *ptr != '"' && *ptr != '>')
  1025. X                *incl_ptr++ = *ptr++;
  1026. X            if (! *ptr) {
  1027. X                err_rpt("missing '\"' or '>' in include file spec", NON_FATAL);
  1028. X                appt->flags |= A_COMMENT;
  1029. X                return(0);
  1030. X            }
  1031. X            *incl_ptr = '\0';
  1032. X            if (strbuf[0] == '/')
  1033. X                /* full pathname provided */
  1034. X                strcpy(incl_buf, strbuf);
  1035. X            else
  1036. X                /* prepend directory info */
  1037. X                if (lib)
  1038. X                    sprintf(incl_buf, "%s/%s", lib_dir, strbuf);
  1039. X                else
  1040. X                    sprintf(incl_buf, "%s/%s", apts_dir, strbuf);
  1041. X            if ((include[include_level] = fopen(incl_buf, "r")) == NULL) {
  1042. X                strcpy(errbuf, "can't open include file <");
  1043. X                strcat(errbuf, incl_buf);
  1044. X                strcat(errbuf, "> (ignored)");
  1045. X                err_rpt(errbuf, NON_FATAL);
  1046. X            } else 
  1047. X                include_level++;
  1048. X        }
  1049. X        appt->flags |= A_COMMENT;
  1050. X        return(0);
  1051. X    }
  1052. X    while (isspace(*ptr))
  1053. X        ++ptr;
  1054. X    if (!*ptr) {
  1055. X        /* empty line */
  1056. X        appt->flags |= A_COMMENT;
  1057. X        return(0);
  1058. X    }
  1059. X    if (*ptr == '*') {
  1060. X        appt->flags |= ALL_YEARS;
  1061. X        appt->year = START_YEAR;
  1062. X        ++ptr;    /* point to second '*' */
  1063. X        ++ptr;    /* point to space */
  1064. X    } else {
  1065. X        appt->year = 0;
  1066. X        while (isdigit(*ptr)) {
  1067. X            appt->year *= 10;
  1068. X            appt->year += *ptr++ - '0';
  1069. X        }
  1070. X        /* sanity check */
  1071. X        if (appt->year < 0) {
  1072. X            sprintf(errbuf, "illegal year value [%d] (ignored)", appt->year);
  1073. X            err_rpt(errbuf, NON_FATAL);
  1074. X            return(1);
  1075. X        }
  1076. X    }
  1077. X    while (isspace(*ptr))
  1078. X        ++ptr;
  1079. X    if (*ptr == '*') {
  1080. X        appt->flags |= ALL_MONTHS;
  1081. X        appt->month = 0;
  1082. X        ++ptr;
  1083. X    } else {
  1084. X        appt->month = (*ptr - '0') * 10;
  1085. X        appt->month += *++ptr - '0';
  1086. X        if (one_based) (appt->month)--;
  1087. X        /* sanity check */
  1088. X        if (appt->month < JAN || appt->month > DEC) {
  1089. X            sprintf(errbuf, "illegal month value [%d] (ignored)", appt->month);
  1090. X            err_rpt(errbuf, NON_FATAL);
  1091. X            return(1);
  1092. X        }
  1093. X    }
  1094. X    ++ptr;
  1095. X    while (isspace(*ptr))
  1096. X        ++ptr;
  1097. X    if (*ptr == '*') {
  1098. X        appt->flags |= ALL_DAYS;
  1099. X        appt->day = 1;
  1100. X        appt->repeat = 1;
  1101. X        ++ptr;
  1102. X    } else if (isdigit(*ptr)) {
  1103. X        appt->day = (*ptr - '0') * 10;
  1104. X        appt->day += *++ptr - '0';
  1105. X        if (!one_based) (appt->day)++;
  1106. X        /* sanity check */
  1107. X        if (appt->day < 1 || appt->day > 31) {
  1108. X            sprintf(errbuf, "illegal day value [%d] (ignored)", appt->day);
  1109. X            err_rpt(errbuf, NON_FATAL);
  1110. X            return(1);
  1111. X        }
  1112. X    } else {
  1113. X        /* check for day names */
  1114. X        wday[0] = islower(*ptr) ? toupper(*ptr) : *ptr;
  1115. X        ++ptr;
  1116. X        wday[1] = islower(*ptr) ? toupper(*ptr) : *ptr;
  1117. X        wday[2] = '\0';
  1118. X        i = 0;
  1119. X        if (!strcmp(wday, dayname[i++]))
  1120. X            appt->flags |= EVERY_SUN;
  1121. X        else if (!strcmp(wday, dayname[i++]))
  1122. X            appt->flags |= EVERY_MON;
  1123. X        else if (!strcmp(wday, dayname[i++]))
  1124. X            appt->flags |= EVERY_TUE;
  1125. X        else if (!strcmp(wday, dayname[i++]))
  1126. X            appt->flags |= EVERY_WED;
  1127. X        else if (!strcmp(wday, dayname[i++]))
  1128. X            appt->flags |= EVERY_THU;
  1129. X        else if (!strcmp(wday, dayname[i++]))
  1130. X            appt->flags |= EVERY_FRI;
  1131. X        else if (!strcmp(wday, dayname[i++]))
  1132. X            appt->flags |= EVERY_SAT;
  1133. X        else if (!strcmp(wday, dayname[i]))
  1134. X            appt->flags |= EVERY_MON_FRI;
  1135. X        else {
  1136. X            /* sanity check */
  1137. X            sprintf(errbuf, "illegal day name [%s] (ignored)", wday);
  1138. X            err_rpt(errbuf, NON_FATAL);
  1139. X            return(1);
  1140. X        }
  1141. X        appt->day = 1;
  1142. X        if (appt->flags & EVERY_MON_FRI) {
  1143. X            appt->repeat = 1;
  1144. X        } else {
  1145. X            appt->flags |= REPEAT;
  1146. X            appt->repeat = ALL_WEEKS;    /* default to every week */
  1147. X        }
  1148. X    }
  1149. X    ++ptr;
  1150. X    while (isspace(*ptr))
  1151. X        ++ptr;
  1152. X    appt->hour = (*ptr - '0') * 10;
  1153. X    appt->hour += *++ptr - '0';
  1154. X    /* sanity check */
  1155. X    if (appt->hour < 0 || (appt->hour > 23 && appt->hour != 99)) {
  1156. X        sprintf(errbuf, "illegal hour value [%d] (ignored)", appt->hour);
  1157. X        err_rpt(errbuf, NON_FATAL);
  1158. X        return(1);
  1159. X    }
  1160. X    if ((version2 && appt->hour == 99) || (!version2 && appt->hour == 0))
  1161. X        appt->flags |= A_NOTE;
  1162. X    ++ptr;
  1163. X    while (isspace(*ptr))
  1164. X        ++ptr;
  1165. X    appt->minute = (*ptr - '0') * 10;
  1166. X    appt->minute += *++ptr - '0';
  1167. X    /* sanity check */
  1168. X    if (appt->minute < 0 || (appt->minute > 59 && appt->minute != 99)) {
  1169. X        /* minutes currently can only be 00 or 30
  1170. X         * unless it's a note.
  1171. X         */
  1172. X        sprintf(errbuf, "illegal minute value [%d] (ignored)", appt->minute);
  1173. X        err_rpt(errbuf, NON_FATAL);
  1174. X        return(1);
  1175. X    }
  1176. X    if ((appt->flags & A_NOTE) && version2 && appt->minute == 99)
  1177. X        appt->flags |= MARKED;  /* don't show in mon/yr display */
  1178. X    ++ptr;
  1179. X    while (isspace(*ptr))
  1180. X        ++ptr;
  1181. X    appt->arrows = (*ptr - '0') * 10;
  1182. X    appt->arrows += *++ptr - '0';
  1183. X    /* sanity check */
  1184. X    if (appt->arrows < 0 || appt->arrows > 48) {
  1185. X        sprintf(errbuf, "illegal arrow value [%d] (ignored)", appt->arrows);
  1186. X        err_rpt(errbuf, NON_FATAL);
  1187. X        return(1);
  1188. X    }
  1189. X    ++ptr;
  1190. X    while (isspace(*ptr))
  1191. X        ++ptr;
  1192. X    /* lookahead and repeat entries are free format, i.e. they */
  1193. X    /* can occur in any order */
  1194. X    parse_options = TRUE;
  1195. X    while (parse_options) {
  1196. X        switch (*ptr) {
  1197. X            case '\\':
  1198. X                /* start of string text */
  1199. X                parse_options = FALSE;
  1200. X                ++ptr;
  1201. X                break;
  1202. X
  1203. X            case '%':
  1204. X                /* advance warning time (minutes) */
  1205. X                appt->warn = 0;
  1206. X                while (isdigit(*++ptr))
  1207. X                    appt->warn = appt->warn * 10 + (int)(*ptr - '0');
  1208. X                if (appt->warn < 0) {
  1209. X                    err_rpt("illegal advance warning (ignored)", NON_FATAL);
  1210. X                    appt->warn = 10;
  1211. X                }
  1212. X                break;
  1213. X
  1214. X            case '[':
  1215. X                /* repeating appointment */
  1216. X                appt->flags |= REPEAT;
  1217. X                if (appt->flags & EVERY_SOMEDAY) {
  1218. X                    if ((appt->repeat = do_wk_repeat(&ptr)) < 0)
  1219. X                        return(1);
  1220. X                } else {
  1221. X                    if ((appt->repeat = do_repeat(&ptr)) < 0)
  1222. X                        return(1);
  1223. X                }
  1224. X                break;
  1225. X            
  1226. X            case '<':
  1227. X                /* remind us ahead of time */
  1228. X                appt->flags |= LOOKAHEAD;
  1229. X                if ((appt->lookahead = do_lookahead(&ptr)) < 0)
  1230. X                    return(1);
  1231. X                break;
  1232. X            
  1233. X            case '+':
  1234. X                /* this appointment lasts for n days */
  1235. X                appt->flags |= RUN;
  1236. X                while (isdigit(*++ptr))
  1237. X                    appt->runlength = appt->runlength * 10 + (int)(*ptr - '0');
  1238. X                if (appt->runlength < 0)
  1239. X                    return(1);
  1240. X                if (!(appt->flags & REPEAT)) {
  1241. X                    /* default to run of days */
  1242. X                    appt->flags |= REPEAT;
  1243. X                    appt->repeat = 1;
  1244. X                }
  1245. X                break;
  1246. X
  1247. X            case '#':
  1248. X                /* deleted appointment */
  1249. X                appt->flags |= DELETED;
  1250. X                ++ptr;
  1251. X                break;
  1252. X            
  1253. X            default:
  1254. X                parse_options = FALSE;
  1255. X                break;
  1256. X        }
  1257. X        while (isspace(*ptr))
  1258. X            ++ptr;
  1259. X    }
  1260. X    str = strbuf;
  1261. X    while (*ptr && *ptr != '\n')
  1262. X        *str++ = *ptr++;
  1263. X    *str = '\0';
  1264. X    strcpy(appt->str, strbuf);
  1265. X    if (appt->flags & DELETED)
  1266. X        /* ignore some flags */
  1267. X        appt->flags &= ~(RUN | REPEAT);
  1268. X
  1269. X    return(0);
  1270. X}
  1271. X
  1272. X/* parse normal repeated entry field */
  1273. Xdo_repeat(ptr)
  1274. Xchar **ptr;
  1275. X{
  1276. X    int repeat = 0;
  1277. X
  1278. X    while (isdigit(*++*ptr))
  1279. X        repeat = repeat * 10 + (int)(**ptr - '0');
  1280. X    if (**ptr != ']') {
  1281. X        err_rpt("bad entry (ignored)", NON_FATAL);
  1282. X        return(-1);
  1283. X    }
  1284. X    /* sanity check */
  1285. X    if (repeat < 0) {
  1286. X        err_rpt("illegal repeat interval (ignored)", NON_FATAL);
  1287. X        return(-1);
  1288. X    }
  1289. X    ++*ptr;
  1290. X    return(repeat);
  1291. X}
  1292. X
  1293. X/* parse weekly repeated entry field */
  1294. Xdo_wk_repeat(ptr)
  1295. Xchar **ptr;
  1296. X{
  1297. X    int repeat = 0;
  1298. X
  1299. X    while (*++*ptr != ']') {
  1300. X        if (**ptr == ',')
  1301. X            continue;    /* get next week */
  1302. X        if (isdigit(**ptr)) {
  1303. X            repeat |= 0x1<<(**ptr - '1');
  1304. X        } else if (**ptr == 'L' || **ptr == 'l') {
  1305. X            /* last week in month */
  1306. X            repeat |= LAST_WEEK;
  1307. X        } else {
  1308. X            /* format error */
  1309. X            err_rpt("illegal repeat specification (ignored)", NON_FATAL);
  1310. X            return(-1);
  1311. X        }
  1312. X    }
  1313. X    /* sanity check */
  1314. X    if ((unsigned int)repeat > WEEK_LIMIT) {
  1315. X        err_rpt("illegal weekly repeat (ignored)", NON_FATAL);
  1316. X        return(-1);
  1317. X    }
  1318. X    ++*ptr;
  1319. X    return(repeat);
  1320. X}
  1321. X
  1322. X/* parse lookahead entry field */
  1323. Xdo_lookahead(ptr)
  1324. Xchar **ptr;
  1325. X{
  1326. X    int lookahead = 0;
  1327. X
  1328. X    while (isdigit(*++*ptr))
  1329. X        lookahead = lookahead * 10 + (int)(**ptr - '0');
  1330. X    if (**ptr != '>') {
  1331. X        err_rpt("bad entry (ignored)", NON_FATAL);
  1332. X        return(-1);
  1333. X    }
  1334. X    /* sanity check */
  1335. X    if (lookahead < 0) {
  1336. X        err_rpt("illegal lookahead interval (ignored)", NON_FATAL);
  1337. X        return(-1);
  1338. X    }
  1339. X    ++*ptr;
  1340. X    return(lookahead);
  1341. X}
  1342. X
  1343. X#ifndef CALENCHECK
  1344. X/*
  1345. X * put entry into appointments file
  1346. X */
  1347. Xput_aentry(apts_file, appt)
  1348. XFILE *apts_file;
  1349. Xstruct appt_entry *appt;
  1350. X{
  1351. X    char *to_str();
  1352. X
  1353. X    if (read_only)
  1354. X        return(0);
  1355. X
  1356. X    if (appt->flags & READONLY)
  1357. X        /* don't copy include file entries */
  1358. X        /* (the include directive is copied as a comment) */
  1359. X        return(0);
  1360. X    if (appt->flags & A_COMMENT) {
  1361. X        fputs(inbuf, apts_file);
  1362. X        return(ferror(apts_file));
  1363. X    }
  1364. X    if (appt->flags & ALL_YEARS)
  1365. X        fputs("** ", apts_file);
  1366. X    else if (appt->year > 99)
  1367. X        fprintf(apts_file, "%03d ", appt->year);
  1368. X    else
  1369. X        fprintf(apts_file, "%02d ", appt->year);
  1370. X    if (appt->flags & ALL_MONTHS)
  1371. X        fputs("** ", apts_file);
  1372. X    else
  1373. X        fprintf(apts_file, "%02d ", one_based ? appt->month+1 : appt->month);
  1374. X    if (appt->flags & ALL_DAYS)
  1375. X        fputs("** ", apts_file);
  1376. X    else if (appt->flags & EVERY_SOMEDAY) {
  1377. X        switch (appt->flags & EVERY_SOMEDAY) {
  1378. X            case EVERY_SUN:
  1379. X                fputs("Su ", apts_file);
  1380. X                break;
  1381. X            case EVERY_MON:
  1382. X                fputs("Mo ", apts_file);
  1383. X                break;
  1384. X            case EVERY_TUE:
  1385. X                fputs("Tu ", apts_file);
  1386. X                break;
  1387. X            case EVERY_WED:
  1388. X                fputs("We ", apts_file);
  1389. X                break;
  1390. X            case EVERY_THU:
  1391. X                fputs("Th ", apts_file);
  1392. X                break;
  1393. X            case EVERY_FRI:
  1394. X                fputs("Fr ", apts_file);
  1395. X                break;
  1396. X            case EVERY_SAT:
  1397. X                fputs("Sa ", apts_file);
  1398. X                break;
  1399. X        }
  1400. X    } else if (appt->flags & EVERY_MON_FRI) {
  1401. X        fputs("MF ", apts_file);
  1402. X    } else
  1403. X        fprintf(apts_file, "%02d ", one_based ? appt->day : appt->day-1);
  1404. X    if (appt->flags & A_NOTE) {
  1405. X        appt->hour = 99;
  1406. X        appt->minute = 0;    /* assume unmarked note */
  1407. X    }
  1408. X    if ((appt->flags & MARKED_NOTE) == MARKED_NOTE)
  1409. X        appt->minute = 99;
  1410. X    if (!(appt->flags & (ALL_DAYS|DELETED|EVERY_MON_FRI)) && appt->flags & REPEAT) {
  1411. X        if (appt->flags & EVERY_SOMEDAY)
  1412. X            fprintf(apts_file, "%02d %02d %02d %s ", appt->hour, appt->minute, appt->arrows, to_str(appt->repeat));
  1413. X        else
  1414. X            fprintf(apts_file, "%02d %02d %02d [%d] ", appt->hour, appt->minute, appt->arrows, appt->repeat);
  1415. X    } else
  1416. X        fprintf(apts_file, "%02d %02d %02d ", appt->hour, appt->minute, appt->arrows);
  1417. X
  1418. X    if (appt->flags & LOOKAHEAD)
  1419. X        fprintf(apts_file, "<%d> ", appt->lookahead);
  1420. X    if (appt->flags & RUN)
  1421. X        fprintf(apts_file, "+%d ", appt->runlength);
  1422. X    if (appt->warn != 10)
  1423. X        fprintf(apts_file, "%%%d ", appt->warn);
  1424. X    if (appt->flags & DELETED)
  1425. X        fputs("# ", apts_file);
  1426. X    if (isalnum(*(appt->str)))
  1427. X        fprintf(apts_file, "%s\n", appt->str);
  1428. X    else
  1429. X        fprintf(apts_file, "\\%s\n", appt->str);
  1430. X    
  1431. X    /* check for failure (e.g. file system full) */
  1432. X    return(ferror(apts_file));
  1433. X}
  1434. X
  1435. Xchar rptstr[10];
  1436. X
  1437. X/* convert repeat bit map to printable string */
  1438. Xchar *
  1439. Xto_str(repeat)
  1440. Xint repeat;
  1441. X{
  1442. X    int i, j = 0;
  1443. X
  1444. X    if (repeat == ALL_WEEKS)
  1445. X        /* if it's every week, then don't write [] spec */
  1446. X        rptstr[0] = '\0';
  1447. X    else {
  1448. X        rptstr[j++] = '[';
  1449. X        for (i=0; i<5; i++) {
  1450. X            if (repeat & (0x1<<i)) {
  1451. X                rptstr[j++] = i+1 + '0';
  1452. X                rptstr[j++] = ',';
  1453. X            }
  1454. X        }
  1455. X        if (repeat & LAST_WEEK) {
  1456. X            rptstr[j++] = 'L';
  1457. X            rptstr[j++] = ',';
  1458. X        }
  1459. X        rptstr[j] = '\0';
  1460. X        rptstr[--j] = ']';
  1461. X    }
  1462. X    return (rptstr);
  1463. X}
  1464. X
  1465. X/*
  1466. X * Convert from version 1 appts files to version 2 file format.
  1467. X */
  1468. Xver1to2()
  1469. X{
  1470. X    FILE *oappts, *nappts, *fp;
  1471. X    struct appt_entry appt;
  1472. X    int err_flag, save_base;
  1473. X    char save_file[128];
  1474. X    struct stat stbuf;
  1475. X
  1476. X    /*
  1477. X     * The main difference is that the ver 2 files are one-based, i.e
  1478. X     * days and months start with 1, rather than 0. Another difference
  1479. X     * is that a hour entry of 99 is used to flag a memo entry, rather
  1480. X     * than 00. This allows for 24-hour appointments.
  1481. X     * Version 2 appts files are marked with a special header line
  1482. X     * defined by the HEADER string (in ct.h).  Version 2 files
  1483. X     * also support a "lookahead" reminder service to remind one
  1484. X     * in advance of a future appointment.
  1485. X     * If "save_old" is set, then any appointments for years prior
  1486. X     * to this one are saved in a special file of the form
  1487. X     * ".appointments.YY", where YY is the year.
  1488. X     */
  1489. X
  1490. X    if (read_only != 0) {
  1491. X        err_rpt("appts file is read-only, no conversion done", NON_FATAL);
  1492. X        return;
  1493. X    }
  1494. X
  1495. X     /* open files, etc */
  1496. X    if ((oappts = fopen(apts_pathname, "r")) == NULL) {
  1497. X        err_rpt("can't open appts file for reading", FATAL);
  1498. X        /* NOT REACHED */
  1499. X     }
  1500. X    if ((nappts = fopen(tmpapts_pathname, "w")) == NULL) {
  1501. X        err_rpt("can't open temp file for writing", NON_FATAL);
  1502. X        return;
  1503. X     }
  1504. X     /* write new header line */
  1505. X     fputs(HEADER, nappts);
  1506. X
  1507. X     /* copy existing entries to the new file */
  1508. X     save_base = one_based;
  1509. X     while ((err_flag = get_aentry(oappts, &appt, TRUE, 0, 0)) != EOF) {
  1510. X        if (err_flag)
  1511. X            continue;    /* ignore badly formatted input */
  1512. X        if (appt.hour == 0)
  1513. X            appt.flags |= A_NOTE;
  1514. X        one_based = 1;        /* force new format output */
  1515. X        if (save_old && !(appt.flags & ALL_YEARS) && (appt.year < today.tm_year)
  1516. X           && !((appt.flags & REPEAT) && !(appt.flags & EVERY_SOMEDAY))
  1517. X           && !(appt.flags & A_COMMENT)) {
  1518. X            /* prepend directory info */
  1519. X            sprintf(save_file, "%s.%02d",
  1520. X                apts_pathname, appt.year);
  1521. X            if (stat(save_file, &stbuf) && errno == ENOENT) {
  1522. X                /* new file*/
  1523. X                if ((fp = fopen(save_file, "w")) == NULL)
  1524. X                    err_rpt("can't open save file, bailing out", FATAL);
  1525. X                fputs(HEADER, fp);
  1526. X                fclose(fp);
  1527. X            }
  1528. X            if ((fp = fopen(save_file, "a+")) == NULL)
  1529. X                err_rpt("can't open save file, bailing out", FATAL);
  1530. X            else {
  1531. X                if (put_aentry(fp, &appt))
  1532. X                    err_rpt("write to save appt file failed, bailing out", FATAL);
  1533. X                fclose(fp);
  1534. X            }
  1535. X        } else {
  1536. X            if (appt.flags & A_COMMENT)
  1537. X                fputs(inbuf, nappts);
  1538. X            else
  1539. X                if (put_aentry(nappts, &appt))
  1540. X                    err_rpt("write to new appt file failed, bailing out", FATAL);
  1541. X        }
  1542. X        one_based = save_base;    /* (maybe) force old format input */
  1543. X    }
  1544. X    fclose(oappts);
  1545. X    fclose(nappts);
  1546. X    xrename(tmpapts_pathname, apts_pathname);
  1547. X    one_based = 1;
  1548. X    version2 = 1;
  1549. X}
  1550. X
  1551. X/*
  1552. X * parse the date on the given string and reset the "current"
  1553. X * date to reflect that date. The date may take the form of a
  1554. X * day name (e.g. Tu, Tue, Tuesday) or a date in m/d/y format
  1555. X * where the month and/or year may be missing (e.g. 27 = 27th
  1556. X * of this month, 8/27 = August 27 of this year, 8/27/89 =
  1557. X * August 27 of 1989. If 'cmdline' is true, then the string
  1558. X * came from the command line '-d' option.
  1559. X * If the first character of the date is + or - scan the number and
  1560. X * use it as an offset in days from the current date.  Thus -1 becomes
  1561. X * yesterday and +1 becomes tomorrow. pbm.
  1562. X */
  1563. Xint
  1564. Xparse_date(str, cmdline)
  1565. Xchar *str;
  1566. Xint cmdline;
  1567. X{
  1568. X    char c[4];
  1569. X    int i, dow = -1, m = -1, d = -1, y = -1;
  1570. X
  1571. X    if (isdigit(*str)) {
  1572. X        /* must be a m/d/y date */
  1573. X        /* assume it's a month first */
  1574. X        m = *str++ - '0';
  1575. X        if (isdigit(*str))
  1576. X            m = m*10 + *str++ - '0';
  1577. X        if (!*str) {
  1578. X            /* no more chars => day only */
  1579. X            d = m;
  1580. X            m = -1;
  1581. X        } else if (*str++ != '/') {
  1582. X            if (cmdline)
  1583. X                err_rpt("badly formed date for -d option (ignored)", NON_FATAL);
  1584. X            else
  1585. X                err_rpt("badly formed date - please reenter", NON_FATAL);
  1586. X            return(1);
  1587. X        } else {
  1588. X            d = *str++ - '0';
  1589. X            if (isdigit(*str))
  1590. X                d = d*10 + *str++ - '0';
  1591. X            if (*str++ == '/') {
  1592. X                /* year also specified */
  1593. X                y = *str++ - '0';
  1594. X                if (isdigit(*str)) {
  1595. X                    y = y*10 + *str++ - '0';
  1596. X                    if (*str && isdigit(*str))
  1597. X                        y = y*10 + *str++ - '0';
  1598. X                    if (*str && isdigit(*str))
  1599. X                        y = y*10 + *str++ - '0';
  1600. X                }
  1601. X            }
  1602. X        }
  1603. X        if (y > 0) {
  1604. X            if (y > 1900)
  1605. X                y -= 1900;
  1606. X            current.tm_year = y;
  1607. X        }
  1608. X        if (day_first) {
  1609. X            if (m > 0) {
  1610. X                current.tm_mon = d - 1;
  1611. X                current.tm_mday = m;
  1612. X            } else if (d > 0)
  1613. X                current.tm_mday = d;
  1614. X        } else {
  1615. X            if (m > 0) {
  1616. X                current.tm_mon = m - 1;
  1617. X                current.tm_mday = d;
  1618. X            } else if (d > 0)
  1619. X                current.tm_mday = d;
  1620. X        }
  1621. X        fix_current_day();
  1622. X    } else if (*str == '-' || *str == '+') {
  1623. X        /*
  1624. X         * If the argument begins with a + or - assume that it is an
  1625. X         * offset in days from the current date. Use current date if the
  1626. X         * number doesn't scan after the - or +. pbm
  1627. X         */
  1628. X        if (sscanf(str, "%d", &i) == 1) {
  1629. X            current.tm_mday += i;
  1630. X            fix_current_day();
  1631. X        }
  1632. X    } else {
  1633. X        /* day of week */
  1634. X        /* check for day names */
  1635. X        c[0] = islower(*str) ? toupper(*str) : *str;
  1636. X        ++str;
  1637. X        c[1] = islower(*str) ? toupper(*str) : *str;
  1638. X        c[2] = '\0';
  1639. X        for (i=0; i<7; i++) {
  1640. X            if (!strcmp(c, dayname[i])) {
  1641. X                dow = i;
  1642. X                break;
  1643. X            }
  1644. X        }
  1645. X        if (dow >= 0) {
  1646. X            /* match found */
  1647. X            current.tm_mday += dow - current.tm_wday;
  1648. X            fix_current_day();
  1649. X        } else if (!strncmp(c, "TOM", 3)) {
  1650. X            /* tommorrow */
  1651. X            current.tm_mday++;
  1652. X            fix_current_day();
  1653. X        } else if (!strncmp(c, "YES", 3)) {
  1654. X            /* yesterday */
  1655. X            current.tm_mday--;
  1656. X            fix_current_day();
  1657. X        } else {
  1658. X            if (cmdline)
  1659. X                err_rpt("badly formed date for -d option (ignored)", NON_FATAL);
  1660. X            else
  1661. X                err_rpt("badly formed date - please reenter", NON_FATAL);
  1662. X            return(1);
  1663. X        }
  1664. X    }
  1665. X    return(0);
  1666. X}
  1667. X#endif  /* CALENCHECK */
  1668. X
  1669. X/* set error logging flag */
  1670. Xerr2console(state)
  1671. Xint state;
  1672. X{
  1673. X    /*
  1674. X     * if TRUE, forces error messages to the console, even
  1675. X     * if the base frame is running
  1676. X     */
  1677. X    log_to_console = state;
  1678. X}
  1679. X
  1680. X/*
  1681. X * Error reporting. Try first to put message in a popup frame, then
  1682. X * the console, then stderr as a last resort.
  1683. X */
  1684. Xerr_rpt(errstr, fatal_flag)
  1685. Xchar *errstr;
  1686. Xint fatal_flag;
  1687. X{
  1688. X    FILE    *f;
  1689. X    int    closed;
  1690. X    char *getenv();
  1691. X
  1692. X#ifndef NOTOOL
  1693. X    closed = (int) window_get(frame, FRAME_CLOSED);
  1694. X    if (frame && !log_to_console && !closed) {
  1695. X        /* base frame exists */
  1696. X        create_prompt_frame(errstr, FALSE);
  1697. X        (void) window_loop(prompt_frame);
  1698. X        window_set(prompt_frame, WIN_SHOW, FALSE, 0);
  1699. X    } else if ((f=fopen("/dev/console", "w")) != NULL) {
  1700. X#else
  1701. X    if (getenv("WINDOW_PARENT") != NULL && (f=fopen("/dev/console", "w")) != NULL) {
  1702. X#endif
  1703. X        fprintf(f, "%s: %s\n", progname, errstr);
  1704. X        fclose(f);
  1705. X    } else
  1706. X        fprintf(stderr, "%s: %s\n", progname, errstr);
  1707. X    if (fatal_flag)
  1708. X        exit(1);
  1709. X}
  1710. X
  1711. X#ifndef CALENCHECK
  1712. X/* Clean-up */
  1713. Xcleanup()
  1714. X{
  1715. X    if (day_is_open)
  1716. X        close_day();
  1717. X
  1718. X    /* create outdated include files (if necessary) */
  1719. X    if (save_old || expire_days)
  1720. X        expire(expire_days);
  1721. X            
  1722. X    /* delete tmp file */
  1723. X    if (access(tmpapts_pathname, R_OK) == 0 && unlink(tmpapts_pathname) < 0)
  1724. X        perror(tmpapts_pathname);
  1725. X}
  1726. X
  1727. Xchar sysbuf[512];
  1728. X
  1729. X/* Rename files, copying if necessary */
  1730. Xxrename(from, to)
  1731. Xchar *from, *to;
  1732. X{
  1733. X    if (rename(from, to) == -1) {
  1734. X        /* rename sys call fialed, try doing a copy */
  1735. X        sprintf(sysbuf, "cp %s %s", from, to);
  1736. X        if (system(sysbuf) != 0)
  1737. X            err_rpt("couldn't rename/copy tmp file", NON_FATAL);
  1738. X    }
  1739. X}
  1740. X
  1741. X/*
  1742. X *  Conventional and ISO standard week numbers (week starts with monday)
  1743. X *  Assume if moday_first is set TRUE then ISO format is desired.
  1744. X */
  1745. X
  1746. Xweek_number()
  1747. X{
  1748. X    int week_n, week_d, W, r, day, year, leap;
  1749. X
  1750. X    /*  First day of this week */
  1751. X    if (monday_first)
  1752. X        week_d = (current.tm_wday?(current.tm_wday-1):6);
  1753. X    else
  1754. X        week_d = current.tm_wday;
  1755. X    current.tm_mday -= week_d;
  1756. X    fix_current_day();
  1757. X    day = current.tm_yday + 1;
  1758. X    week_n = day / 7 + 1;       /*  "Raw" week number  */ 
  1759. X    r = day % 7 - 1;           /*  No of days in the first week this year  */
  1760. X
  1761. X    if (!monday_first) {
  1762. X        if (week_n == 53)
  1763. X            week_n = 1;
  1764. X        else if (r > 0 && day > r)
  1765. X            if (++week_n == 53 && (day + 6) > length_of_year(current.tm_year+1900))
  1766. X                week_n = 1;
  1767. X    } else {
  1768. X        if (r >= 4) week_n++;       /*  First week has more than three days  */
  1769. X        if (week_n == 53) {         /*  Week number of last week of year  */
  1770. X            year = current.tm_year + 1900;
  1771. X            leap = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);   
  1772. X            day += 7 - ( leap ? 366 : 365 );
  1773. X            W = day / 7 + 1;
  1774. X            r = day % 7 - 1;
  1775. X            if (r >= 4) W++;
  1776. X            if (W == 2) week_n = 1;
  1777. X            }
  1778. X    }
  1779. X    current.tm_mday += week_d;
  1780. X    fix_current_day();
  1781. X    return week_n;
  1782. X}
  1783. X#endif  /* CALENCHECK */
  1784. END_OF_FILE
  1785. if test 29701 -ne `wc -c <'utils.c'`; then
  1786.     echo shar: \"'utils.c'\" unpacked with wrong size!
  1787. fi
  1788. # end of 'utils.c'
  1789. fi
  1790. echo shar: End of archive 16 \(of 23\).
  1791. cp /dev/null ark16isdone
  1792. MISSING=""
  1793. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
  1794.     if test ! -f ark${I}isdone ; then
  1795.     MISSING="${MISSING} ${I}"
  1796.     fi
  1797. done
  1798. if test "${MISSING}" = "" ; then
  1799.     echo You have unpacked all 23 archives.
  1800.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1801. else
  1802.     echo You still need to unpack the following archives:
  1803.     echo "        " ${MISSING}
  1804. fi
  1805. ##  End of shell archive.
  1806. exit 0
  1807.  
  1808. exit 0 # Just in case...
  1809. -- 
  1810. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1811. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1812. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1813. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1814.